import csv
from line import Line, Station


def find_neighbour(line_dict: dict, name: str):
    """
    找到相交线路
    :param line_dict:线路字典
    :param name:目标线路的名字
    :return:目标线路的邻居
    """
    neighbours = {}
    for key in line_dict.keys():
        temp_neighbour = []
        is_neighbour = False
        if (key != name):  # 遍历自己之外的所有线路
            temp_station = line_dict[key].stations
            for station_key in temp_station.keys():
                if station_key in line_dict[name].stations.keys():  # 如果有相同站
                    temp_neighbour.append(station_key)
                    line_dict[name].stations[station_key].isTrans = True
                    # python中可以修改形参
                    is_neighbour = True
            if is_neighbour:
                neighbours[key] = temp_neighbour
    # neighbours = {"2号线":["西直门","东直门"]}邻接点
    return neighbours


def read_line():
    """
    读取文件，返回储存有线路信息的字典
    :return:
    """
    csv_reader = csv.DictReader(open("base.csv", encoding='utf-8-sig'))
    line_dict = {}
    # dir1First	dir1Last	dir2First	dir2Last	gapTime	isLoop	loopTime	speed
    for row in csv_reader:
        temp_dir = []
        temp_time = row['dir1First'].split(':')
        temp_dir.append(3600 * int(temp_time[0]) + 60 * int(temp_time[1]))
        temp_time = row['dir1Last'].split(':')
        temp_dir.append(3600 * int(temp_time[0]) + 60 * int(temp_time[1]))
        temp_time = row['dir2First'].split(':')
        temp_dir.append(3600 * int(temp_time[0]) + 60 * int(temp_time[1]))
        temp_time = row['dir2Last'].split(':')
        temp_dir.append(3600 * int(temp_time[0]) + 60 * int(temp_time[1]))
        # 以上是把字符串时间转换为分钟为单位的数字
        temp_line = Line(row['name'], temp_dir, int(row['gapTime'])*60, int(row['isLoop']), int(row['loopTime']),
                         float(row['speed']) * 1000 / 3600)

        # 读取时刻表文件/获取站台名称
        line_reader = csv.DictReader(open("./timeMap/" + f"{row['name']}.csv", encoding='utf-8-sig'))
        for station_item in line_reader:
            temp_time = station_item['dir1'].split(':')
            temp_station = Station(station_item['name'], 3600 * int(temp_time[0]) + 60 * int(temp_time[1]))
            temp_line.stations[station_item['name']] = temp_station

        # 读取间距文件
        line_reader = list(csv.reader(open("./lengthMap/" + f"{row['name']}.csv", encoding='utf-8-sig')))
        # print(temp_line.name) 14号线问题很多，资料不全，有的站已经永久取消了京港地铁的官网上面居然还有
        for station_raw in line_reader:
            station1, station2, distance = station_raw
            distance = int(distance)
            # if temp_line.stations[station1].neighbours == {}:  # 如果当前站的邻居不存在
            temp_line.stations[station1].neighbours[station2] = {
                "dist": distance,
                "time": round(distance / temp_line.speed)
                # 分钟数四舍五入取整
            }
            temp_line.stations[station2].neighbours[station1] = {
                "dist": distance,
                "time": round(distance / temp_line.speed)
            }

        line_dict[row['name']] = temp_line

    for key in line_dict.keys():
        line_dict[key].neighbours = find_neighbour(line_dict, key)
    return line_dict


def find_station(station_name: str, line_dict: dict):
    """
    查找一个站台的信息
    :param station_name: 站台名称
    :param line_dict: 线路字典
    :return:station_info = {
        "isFind": False,
        "lines": []
    }
    """
    station_info = {
        "isFind": False,
        "lines": []
    }
    for line_name in line_dict.keys():
        temp_line = line_dict[line_name]
        if station_name in temp_line.stations.keys():
            # 如果包含了该站
            station_info["isFind"] = True
            station_info["lines"].append(temp_line.name)
    return station_info


def delete_station(line_name: str, station_name: str, line_dict: dict) -> dict:
    """
    删除指定线路中的特定站点，并维护线路连接关系
    :param line_name: 目标线路名称
    :param station_name: 要删除的站点名称
    :param line_dict: 线路数据字典
    :return: 操作结果 {
        "success": bool,
        "message": str,
        "affected_stations": list 受影响的相邻站点
    }
    """
    result = {
        "success": False,
        "message": "",
        "affected_stations": []
    }

    # 验证线路存在
    if line_name not in line_dict:
        result["message"] = f"线路 {line_name} 不存在"
        return result

    line = line_dict[line_name]
    stations = line.stations

    # 验证站点存在
    if station_name not in stations:
        result["message"] = f"站点 {station_name} 不在线路 {line_name} 中"
        return result

    # 获取目标站点实例
    target_station = stations[station_name]

    # 处理相邻站点连接（当线路包含多个站点时）
    if len(stations) > 1:
        neighbors = list(target_station.neighbours.keys())

        # 重建相邻站点间的连接
        if len(neighbors) == 2:  # 中间站点
            sta1, sta2 = neighbors
            dist_sum = (target_station.neighbours[sta1]["dist"] +
                        target_station.neighbours[sta2]["dist"])
            time_sum = (target_station.neighbours[sta1]["time"] +
                        target_station.neighbours[sta2]["time"])

            # 更新前后站点的连接
            stations[sta1].neighbours[sta2] = {"dist": dist_sum, "time": time_sum}
            stations[sta2].neighbours[sta1] = {"dist": dist_sum, "time": time_sum}
            result["affected_stations"] = [sta1, sta2]

        elif len(neighbors) == 1:  # 端点站
            neighbor = neighbors[0]
            del stations[neighbor].neighbours[station_name]
            result["affected_stations"] = [neighbor]

    # 更新换乘信息
    for neighbor_line, trans_stations in list(line.neighbours.items()):
        if station_name in trans_stations:
            # 从换乘站列表中移除
            trans_stations.remove(station_name)
            # 如果该线路换乘站列表为空则删除
            if not trans_stations:
                del line.neighbours[neighbor_line]

    # 执行删除操作
    del stations[station_name]

    # 处理线路属性
    if not stations:
        result["message"] = f"警告：线路 {line_name} 已无站点"
    else:
        result["message"] = f"站点 {station_name} 已从线路 {line_name} 删除"

    result["success"] = True

    # 重新生成换乘信息
    for line_name in line_dict:
        line_dict[line_name].neighbours = find_neighbour(line_dict, line_name)

    return result

def delete_line(line_name: str, line_dict: dict) -> dict:
    """
    删除指定线路并清理关联线路的换乘信息
    :param line_name: 要删除的线路名称
    :param line_dict: 线路数据字典
    :return: 操作结果 {
        "success": bool,
        "message": str,
        "deleted_stations": int,
        "affected_lines": list 受影响的关联线路
    }
    """
    result = {
        "success": False,
        "message": "",
        "deleted_stations": 0,
        "affected_lines": []
    }

    # 验证线路存在
    if line_name not in line_dict:
        result["message"] = f"线路 {line_name} 不存在"
        return result

    # 获取目标线路实例
    target_line = line_dict[line_name]

    # 记录删除信息
    station_count = len(target_line.stations)
    result["deleted_stations"] = station_count

    # 清理其他线路的换乘信息
    affected_lines = set()
    for other_line in line_dict.values():
        if line_name in other_line.neighbours:
            # 删除与该线路的换乘关联
            del other_line.neighbours[line_name]
            affected_lines.add(other_line.name)

    result["affected_lines"] = list(affected_lines)

    # 执行删除操作
    del line_dict[line_name]

    # 生成结果
    result["success"] = True
    result["message"] = (
        f"已删除线路 {line_name}（共{station_count}个站点），"
        f"影响{len(affected_lines)}条关联线路"
    )
    return result


def add_station(line_name: str, station_name: str, front_station: str,
                distance: int, line_dict: dict) -> dict:
    result = {
        "success": False,
        "message": "",
        "new_vtime": 0
    }

    if line_name not in line_dict:
        result["message"] = f"线路 {line_name} 不存在"
        return result

    line = line_dict[line_name]
    stations = line.stations

    if station_name in stations:
        result["message"] = f"站点 {station_name} 已在线路 {line_name} 中存在"
        return result

    # 处理空线路情况
    if not stations:
        # if front_station is not None:
        #     result["message"] = "不能指定前序站点（空线路添加首个站点）"
        #     return result

        new_station = Station(station_name, line.dir1First)
        stations[station_name] = new_station
        result["success"] = True
        result["new_vtime"] = line.dir1First
        result["message"] = f"成功创建空线路 {line_name} 的首个站点 {station_name}"
        return result

    try:
        time = round(distance / line.speed)
    except ZeroDivisionError:
        result["message"] = "无效的车速参数"
        return result

    # 处理添加到线路开头
    if not front_station:
        first_station = next(iter(stations.values()))

        new_station = Station(station_name, line.dir1First)
        new_station.neighbours[first_station.name] = {"dist": distance, "time": time}
        first_station.neighbours[station_name] = {"dist": distance, "time": time}

        # 更新其他站点时间（当线路已有多个站点时）
        if len(stations) > 1:
            time_diff = time + line.dir1First
            for s in stations.values():
                s.vTime += time_diff

        stations[station_name] = new_station
        result["new_vtime"] = line.dir1First

    # 处理添加到指定站点后方
    else:
        if front_station not in stations:
            result["message"] = f"前序站点 {front_station} 不在线路 {line_name} 中"
            return result

        front = stations[front_station]
        next_station = None  # 显式初始化

        # 获取第一个有效后续站点
        next_stations = [n for n in front.neighbours if n in stations]
        if next_stations:
            next_station = stations[next_stations[0]]

        # 创建新站点
        new_vtime = front.vTime + time
        new_station = Station(station_name, new_vtime)
        result["new_vtime"] = new_vtime

        # 建立双向连接
        front.neighbours[station_name] = {"dist": distance, "time": time}
        new_station.neighbours[front_station] = {"dist": distance, "time": time}

        # 处理后续连接（仅当存在后续站点时）
        if next_station:
            original_dist = front.neighbours[next_station.name]["dist"]
            original_time = front.neighbours[next_station.name]["time"]

            del front.neighbours[next_station.name]
            del next_station.neighbours[front_station]

            new_dist = original_dist - distance
            if new_dist <= 0:
                result["message"] = "无效的距离参数，导致负距离"
                return result

            new_time = round(new_dist / line.speed)
            new_station.neighbours[next_station.name] = {"dist": new_dist, "time": new_time}
            next_station.neighbours[station_name] = {"dist": new_dist, "time": new_time}

        # 处理线路只有一个站的情况
        elif len(stations) == 1:
            # 当添加第二个站时自动形成双向连接
            station_names = list(stations.keys())
            existing_station = stations[station_names[0]]

            existing_station.neighbours[station_name] = {"dist": distance, "time": time}
            new_station.neighbours[existing_station.name] = {"dist": distance, "time": time}

        stations[station_name] = new_station

    # 更新换乘信息
    line.neighbours = find_neighbour(line_dict, line_name)
    print(list(line_dict.values())[-1].stations)
    result["success"] = True
    result["message"] = f"成功添加站点 {station_name} 到线路 {line_name}"
    return result


def add_line(name: str,gapTime: int,speed: float,dir: list,line_dict: dict) -> dict:
    """
    创建新线路（默认非环线）
    :param name: 线路名称
    :param gapTime: 发车间隔（秒）
    :param speed: 运行速度（米/秒）
    :param dir: 首末班车时间
    :param line_dict: 线路数据字典
    :return: 操作结果 {
        "success": bool,
        "message": str,
        "new_line": dict 新线路基础信息
    }
    """
    result = {
        "success": False,
        "message": "",
        "new_line": None
    }
    dir1_first = dir[0]
    dir1_last = dir[1]
    # 验证线路名称唯一性
    if name in line_dict:
        result["message"] = f"线路 {name} 已存在"
        return result

    # 验证时间有效性
    if dir1_first >= dir1_last:
        result["message"] = "首班车时间不能晚于末班车时间"
        return result

    # 创建线路参数
    new_line = Line(
        name=name,
        dir=dir,  # 方向2时间设为0
        gapTime=gapTime,
        isLoop=0,  # 默认非环线
        loopTime=0,
        speed=speed
    )

    # 添加空线路
    line_dict[name] = new_line

    # 构造返回信息
    result["success"] = True
    result["message"] = f"成功创建线路 {name}"
    result["new_line"] = {
        "line_name": name,
        "is_loop": False,
        "dir1_first": dir1_first,
        "dir1_last": dir1_last,
        "gap_time": gapTime,
        "speed": speed,
        "station_count": 0
    }
    return result


if __name__ == '__main__':
    lineDict = read_line()
    for item in lineDict.keys():
        print(f"{item}")
    # temp_info = find_station("北京南站", lineDict)
    # print(add_station("2号线","共和门","西直门",100,lineDict))
    # print(lineDict['2号线'].stations['共和门'].neighbours)
    # temp_info = find_station("西直门", lineDict)
    # 创建新线路
    result = add_line(
        name="28号线",
        gapTime=300,  # 5分钟间隔
        speed=16.67,  # 约60公里/小时
        dir = [1000,2000,1000,2000],
        line_dict=lineDict
    )

    # 向空线路添加首站
    add_result = add_station(
        line_name="28号线",
        station_name="CBD东站",
        front_station=None,
        distance=0,  # 首站无距离
        line_dict=lineDict
    )
    print(add_result)

    # 添加后续站点
    add_result = add_station(
        line_name="28号线",
        station_name="大望路站",
        front_station="CBD东站",
        distance=1500,
        line_dict=lineDict
    )
    print(add_result)
    print(1)

